package com.woniu.tmsorder.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.woniu.tmscommons.entity.Vehicle;
import com.woniu.tmscommons.enums.VehicleBelongStatus;
import com.woniu.tmsorder.mapper.vehiclePositionMapper;
import com.woniu.tmsorder.service.vehiclePositionService;
import com.woniu.tmsorder.vo.vehiclePositionVo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisCommand;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.Resource;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lio
 * @create 2024-09-06 15:12
 */
@Service
public class vehiclePositionServiceImpl implements vehiclePositionService {
    @Resource
    private vehiclePositionMapper vehiclePositionMapper;
    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    /**
     * 更新车辆位置信息
     * @param vo
     */
    @Override
    public void updateVehiclePosition(vehiclePositionVo vo) {
        //更新数据库中的位置信息
        LambdaUpdateWrapper<Vehicle> wrapper=new LambdaUpdateWrapper<>();
        wrapper.eq(Vehicle::getId,vo.getVehicleId());
        wrapper.set(Vehicle::getLag,vo.getLatitude());//纬度
        wrapper.set(Vehicle::getLng,vo.getLongitude());//经度
        vehiclePositionMapper.update(wrapper);
        //将位置信息跟新到redis中
        redisTemplate.opsForGeo().add("vehicle_Position",new Point(vo.getLongitude(),vo.getLatitude()),vo.getVehicleId());
    }

    /**
     * 将所有自家公司的车辆位置信息存储到redis中
     */
    @Override
    public void addAllVehiclePosition() {
        //获取所有属于自家车辆
        LambdaQueryWrapper<Vehicle> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Vehicle::getVehicleBelong, VehicleBelongStatus.OUR);
        List<Vehicle> vehicles = vehiclePositionMapper.selectList(wrapper);
        //把他们的经纬度位置存储到redis中
        Map<Object,Point> map=new HashMap<>();
        for (Vehicle vehicle : vehicles) {
            map.put(String.valueOf(vehicle.getId()), new Point(vehicle.getLng().doubleValue(),vehicle.getLag().doubleValue()));
        }
        redisTemplate.opsForGeo().add("vehicle_Position",map);
    }
    @Value("${gaodeMap.key}")
    private String key;
    @Value("${gaodeMap.url}")
    private String url;
    @Resource
    private RestTemplate restTemplate;
    @Override
    public GeoResults getSenderAddressPosition(String senderAddress) {
        URI uri = UriComponentsBuilder.fromHttpUrl(url)
                .queryParam("key", key)
                .queryParam("address", senderAddress)
                .encode(StandardCharsets.UTF_8)
                .build()
                .toUri();

        // 发送GET请求
        ResponseEntity<Map> response = restTemplate.getForEntity(uri, Map.class);
        if (response.getStatusCode().is2xxSuccessful()) {
            Map body = response.getBody();
            if (body != null) {
                List<Object> geocodes = (ArrayList) body.get("geocodes");
                if (geocodes.size() > 0) {
                    Map<String, Object> location = (Map<String, Object>) geocodes.get(0);
                    String location1 = (String) location.get("location");
                    String[] split = location1.split(",");
                    double lng = Double.parseDouble(split[0]);
                    double lat = Double.parseDouble(split[1]);
                    Circle circle = new Circle(lng, lat, 5000*1000);
                    RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeCoordinates().includeDistance().sortAscending().limit(1);
                    GeoResults<RedisGeoCommands.GeoLocation<Object>> vehiclePosition = redisTemplate.opsForGeo().radius("vehicle_Position", circle, args);
                    System.out.println(vehiclePosition);
                    return vehiclePosition;
                }
            }
        } else {
            throw new RuntimeException("Failed to get geocoding data from AMap API.");
        }
        return null;
    }
}
